//! # RBAC (Role-Based Access Control) 基于角色的访问控制
//!
//! 提供企业级的角色和权限管理功能

use rustcloud_security::prelude::*;
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
use std::sync::Arc;
use tokio::sync::RwLock;
use uuid::Uuid;
use chrono::{DateTime, Utc};

/// 角色管理器
#[derive(Clone)]
pub struct RoleManager {
    inner: Arc<RoleManagerInner>,
}

/// 权限管理器
#[derive(Clone)]
pub struct PermissionManager {
    inner: Arc<PermissionManagerInner>,
}

/// 策略引擎
#[derive(Clone)]
pub struct PolicyEngine {
    role_manager: RoleManager,
    permission_manager: PermissionManager,
    policies: Arc<RwLock<HashMap<String, AccessPolicy>>>,
}

struct RoleManagerInner {
    roles: RwLock<HashMap<String, Role>>,
    user_roles: RwLock<HashMap<String, HashSet<String>>>,
}

struct PermissionManagerInner {
    permissions: RwLock<HashMap<String, Permission>>,
    role_permissions: RwLock<HashMap<String, HashSet<String>>>,
}

/// 角色定义
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Role {
    /// 角色ID
    pub id: String,
    /// 角色名称
    pub name: String,
    /// 角色描述
    pub description: Option<String>,
    /// 角色类型
    pub role_type: RoleType,
    /// 角色范围
    pub scope: RoleScope,
    /// 创建时间
    pub created_at: DateTime<Utc>,
    /// 更新时间
    pub updated_at: DateTime<Utc>,
    /// 是否启用
    pub enabled: bool,
    /// 角色属性
    pub attributes: HashMap<String, String>,
}

/// 权限定义
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Permission {
    /// 权限ID
    pub id: String,
    /// 权限名称
    pub name: String,
    /// 权限描述
    pub description: Option<String>,
    /// 资源类型
    pub resource_type: String,
    /// 操作类型
    pub action: String,
    /// 权限范围
    pub scope: PermissionScope,
    /// 创建时间
    pub created_at: DateTime<Utc>,
    /// 是否启用
    pub enabled: bool,
}

/// 访问策略
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AccessPolicy {
    /// 策略ID
    pub id: String,
    /// 策略名称
    pub name: String,
    /// 策略描述
    pub description: Option<String>,
    /// 策略规则
    pub rules: Vec<PolicyRule>,
    /// 策略效果
    pub effect: PolicyEffect,
    /// 创建时间
    pub created_at: DateTime<Utc>,
    /// 是否启用
    pub enabled: bool,
}

/// 策略规则
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PolicyRule {
    /// 主体匹配条件
    pub subject: SubjectCondition,
    /// 资源匹配条件
    pub resource: ResourceCondition,
    /// 操作匹配条件
    pub action: ActionCondition,
    /// 环境条件
    pub conditions: Vec<EnvironmentCondition>,
}

/// 角色类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RoleType {
    /// 系统角色
    System,
    /// 组织角色
    Organization,
    /// 应用角色
    Application,
    /// 自定义角色
    Custom,
}

/// 角色范围
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RoleScope {
    /// 全局范围
    Global,
    /// 组织范围
    Organization(String),
    /// 应用范围
    Application(String),
    /// 资源范围
    Resource(String),
}

/// 权限范围
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum PermissionScope {
    /// 全局权限
    Global,
    /// 服务权限
    Service(String),
    /// 资源权限
    Resource(String),
    /// 实例权限
    Instance(String),
}

/// 策略效果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum PolicyEffect {
    /// 允许
    Allow,
    /// 拒绝
    Deny,
}

/// 主体条件
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SubjectCondition {
    /// 用户ID模式
    pub user_ids: Option<Vec<String>>,
    /// 角色模式
    pub roles: Option<Vec<String>>,
    /// 组模式
    pub groups: Option<Vec<String>>,
}

/// 资源条件
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResourceCondition {
    /// 服务名称
    pub service: Option<String>,
    /// 资源路径模式
    pub path_pattern: Option<String>,
    /// 资源类型
    pub resource_type: Option<String>,
}

/// 操作条件
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ActionCondition {
    /// HTTP方法
    pub methods: Option<Vec<String>>,
    /// 操作类型
    pub actions: Option<Vec<String>>,
}

/// 环境条件
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EnvironmentCondition {
    /// 条件类型
    pub condition_type: EnvironmentConditionType,
    /// 操作符
    pub operator: ConditionOperator,
    /// 期望值
    pub value: String,
}

/// 环境条件类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum EnvironmentConditionType {
    /// IP地址
    IpAddress,
    /// 时间范围
    TimeRange,
    /// 地理位置
    Location,
    /// 用户代理
    UserAgent,
    /// 自定义属性
    Custom(String),
}

/// 条件操作符
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ConditionOperator {
    /// 等于
    Equals,
    /// 不等于
    NotEquals,
    /// 包含
    Contains,
    /// 不包含
    NotContains,
    /// 在范围内
    InRange,
    /// 不在范围内
    NotInRange,
    /// 匹配正则
    Matches,
    /// 不匹配正则
    NotMatches,
}

impl RoleManager {
    /// 创建新的角色管理器
    pub fn new() -> Self {
        Self {
            inner: Arc::new(RoleManagerInner {
                roles: RwLock::new(HashMap::new()),
                user_roles: RwLock::new(HashMap::new()),
            }),
        }
    }

    /// 创建角色
    pub async fn create_role(&self, mut role: Role) -> SecurityResult<()> {
        role.created_at = Utc::now();
        role.updated_at = role.created_at;
        
        let mut roles = self.inner.roles.write().await;
        if roles.contains_key(&role.id) {
            return Err(SecurityError::AlreadyExists {
                resource: "role".to_string(),
                id: role.id,
            });
        }
        
        roles.insert(role.id.clone(), role);
        Ok(())
    }

    /// 获取角色
    pub async fn get_role(&self, role_id: &str) -> SecurityResult<Option<Role>> {
        let roles = self.inner.roles.read().await;
        Ok(roles.get(role_id).cloned())
    }

    /// 列出所有角色
    pub async fn list_roles(&self) -> SecurityResult<Vec<Role>> {
        let roles = self.inner.roles.read().await;
        Ok(roles.values().cloned().collect())
    }

    /// 更新角色
    pub async fn update_role(&self, role_id: &str, mut role: Role) -> SecurityResult<()> {
        role.updated_at = Utc::now();
        
        let mut roles = self.inner.roles.write().await;
        match roles.get_mut(role_id) {
            Some(existing_role) => {
                role.created_at = existing_role.created_at; // 保持创建时间
                *existing_role = role;
                Ok(())
            },
            None => Err(SecurityError::NotFound {
                resource: "role".to_string(),
                id: role_id.to_string(),
            }),
        }
    }

    /// 删除角色
    pub async fn delete_role(&self, role_id: &str) -> SecurityResult<()> {
        let mut roles = self.inner.roles.write().await;
        let mut user_roles = self.inner.user_roles.write().await;
        
        // 检查角色是否存在
        if !roles.contains_key(role_id) {
            return Err(SecurityError::NotFound {
                resource: "role".to_string(),
                id: role_id.to_string(),
            });
        }
        
        // 从所有用户中移除该角色
        for (_, roles_set) in user_roles.iter_mut() {
            roles_set.remove(role_id);
        }
        
        // 删除角色
        roles.remove(role_id);
        Ok(())
    }

    /// 为用户分配角色
    pub async fn assign_role_to_user(&self, user_id: &str, role_id: &str) -> SecurityResult<()> {
        // 检查角色是否存在
        let roles = self.inner.roles.read().await;
        if !roles.contains_key(role_id) {
            return Err(SecurityError::NotFound {
                resource: "role".to_string(),
                id: role_id.to_string(),
            });
        }
        drop(roles);
        
        let mut user_roles = self.inner.user_roles.write().await;
        user_roles
            .entry(user_id.to_string())
            .or_insert_with(HashSet::new)
            .insert(role_id.to_string());
        
        Ok(())
    }

    /// 从用户移除角色
    pub async fn remove_role_from_user(&self, user_id: &str, role_id: &str) -> SecurityResult<()> {
        let mut user_roles = self.inner.user_roles.write().await;
        if let Some(roles_set) = user_roles.get_mut(user_id) {
            roles_set.remove(role_id);
            if roles_set.is_empty() {
                user_roles.remove(user_id);
            }
        }
        Ok(())
    }

    /// 获取用户的所有角色
    pub async fn get_user_roles(&self, user_id: &str) -> SecurityResult<Vec<Role>> {
        let user_roles = self.inner.user_roles.read().await;
        let roles = self.inner.roles.read().await;
        
        let mut user_role_list = Vec::new();
        if let Some(role_ids) = user_roles.get(user_id) {
            for role_id in role_ids {
                if let Some(role) = roles.get(role_id) {
                    user_role_list.push(role.clone());
                }
            }
        }
        
        Ok(user_role_list)
    }
}

impl PermissionManager {
    /// 创建新的权限管理器
    pub fn new() -> Self {
        Self {
            inner: Arc::new(PermissionManagerInner {
                permissions: RwLock::new(HashMap::new()),
                role_permissions: RwLock::new(HashMap::new()),
            }),
        }
    }

    /// 创建权限
    pub async fn create_permission(&self, mut permission: Permission) -> SecurityResult<()> {
        permission.created_at = Utc::now();
        
        let mut permissions = self.inner.permissions.write().await;
        if permissions.contains_key(&permission.id) {
            return Err(SecurityError::AlreadyExists {
                resource: "permission".to_string(),
                id: permission.id,
            });
        }
        
        permissions.insert(permission.id.clone(), permission);
        Ok(())
    }

    /// 获取权限
    pub async fn get_permission(&self, permission_id: &str) -> SecurityResult<Option<Permission>> {
        let permissions = self.inner.permissions.read().await;
        Ok(permissions.get(permission_id).cloned())
    }

    /// 为角色分配权限
    pub async fn assign_permission_to_role(&self, role_id: &str, permission_id: &str) -> SecurityResult<()> {
        // 检查权限是否存在
        let permissions = self.inner.permissions.read().await;
        if !permissions.contains_key(permission_id) {
            return Err(SecurityError::NotFound {
                resource: "permission".to_string(),
                id: permission_id.to_string(),
            });
        }
        drop(permissions);
        
        let mut role_permissions = self.inner.role_permissions.write().await;
        role_permissions
            .entry(role_id.to_string())
            .or_insert_with(HashSet::new)
            .insert(permission_id.to_string());
        
        Ok(())
    }

    /// 获取角色的所有权限
    pub async fn get_role_permissions(&self, role_id: &str) -> SecurityResult<Vec<Permission>> {
        let role_permissions = self.inner.role_permissions.read().await;
        let permissions = self.inner.permissions.read().await;
        
        let mut role_permission_list = Vec::new();
        if let Some(permission_ids) = role_permissions.get(role_id) {
            for permission_id in permission_ids {
                if let Some(permission) = permissions.get(permission_id) {
                    role_permission_list.push(permission.clone());
                }
            }
        }
        
        Ok(role_permission_list)
    }
}

impl PolicyEngine {
    /// 创建新的策略引擎
    pub fn new(role_manager: RoleManager, permission_manager: PermissionManager) -> Self {
        Self {
            role_manager,
            permission_manager,
            policies: Arc::new(RwLock::new(HashMap::new())),
        }
    }

    /// 评估访问策略
    pub async fn evaluate_policy(
        &self,
        principal: &Principal,
        resource: &Resource,
        context: &AuthContext,
    ) -> SecurityResult<AuthorizationResult> {
        // 获取用户角色
        let user_roles = self.role_manager.get_user_roles(&principal.id).await?;
        
        // 收集所有权限
        let mut all_permissions = Vec::new();
        for role in &user_roles {
            let role_permissions = self.permission_manager.get_role_permissions(&role.id).await?;
            all_permissions.extend(role_permissions);
        }
        
        // 评估权限
        let mut has_permission = false;
        for permission in &all_permissions {
            if self.matches_permission(permission, resource).await? {
                has_permission = true;
                break;
            }
        }
        
        // 评估策略
        let policies = self.policies.read().await;
        let mut policy_result = None;
        
        for policy in policies.values() {
            if !policy.enabled {
                continue;
            }
            
            if self.matches_policy(policy, principal, resource, context).await? {
                policy_result = Some(policy.effect.clone());
                if matches!(policy.effect, PolicyEffect::Deny) {
                    // 拒绝策略优先
                    break;
                }
            }
        }
        
        // 决定最终结果
        let authorized = match policy_result {
            Some(PolicyEffect::Deny) => false,
            Some(PolicyEffect::Allow) => true,
            None => has_permission, // 没有明确策略时依赖权限
        };
        
        Ok(AuthorizationResult {
            authorized,
            reason: if authorized {
                "Access granted".to_string()
            } else {
                "Access denied".to_string()
            },
            roles: user_roles.into_iter().map(|r| r.name).collect(),
            permissions: all_permissions.into_iter().map(|p| p.name).collect(),
        })
    }

    /// 添加访问策略
    pub async fn add_policy(&self, policy: AccessPolicy) -> SecurityResult<()> {
        let mut policies = self.policies.write().await;
        policies.insert(policy.id.clone(), policy);
        Ok(())
    }

    /// 检查权限是否匹配资源
    async fn matches_permission(&self, permission: &Permission, resource: &Resource) -> SecurityResult<bool> {
        // 检查资源类型
        if permission.resource_type != "*" && permission.resource_type != resource.service {
            return Ok(false);
        }
        
        // 检查操作
        if permission.action != "*" && permission.action != resource.action {
            return Ok(false);
        }
        
        Ok(true)
    }

    /// 检查策略是否匹配
    async fn matches_policy(
        &self,
        policy: &AccessPolicy,
        principal: &Principal,
        resource: &Resource,
        context: &AuthContext,
    ) -> SecurityResult<bool> {
        for rule in &policy.rules {
            if self.matches_rule(rule, principal, resource, context).await? {
                return Ok(true);
            }
        }
        Ok(false)
    }

    /// 检查规则是否匹配
    async fn matches_rule(
        &self,
        rule: &PolicyRule,
        principal: &Principal,
        resource: &Resource,
        context: &AuthContext,
    ) -> SecurityResult<bool> {
        // 检查主体条件
        if !self.matches_subject_condition(&rule.subject, principal).await? {
            return Ok(false);
        }
        
        // 检查资源条件
        if !self.matches_resource_condition(&rule.resource, resource).await? {
            return Ok(false);
        }
        
        // 检查操作条件
        if !self.matches_action_condition(&rule.action, resource).await? {
            return Ok(false);
        }
        
        // 检查环境条件
        for condition in &rule.conditions {
            if !self.matches_environment_condition(condition, context).await? {
                return Ok(false);
            }
        }
        
        Ok(true)
    }

    async fn matches_subject_condition(&self, condition: &SubjectCondition, principal: &Principal) -> SecurityResult<bool> {
        // 检查用户ID
        if let Some(user_ids) = &condition.user_ids {
            if !user_ids.contains(&principal.id) {
                return Ok(false);
            }
        }
        
        // 检查角色
        if let Some(required_roles) = &condition.roles {
            let user_roles = self.role_manager.get_user_roles(&principal.id).await?;
            let user_role_names: HashSet<String> = user_roles.into_iter().map(|r| r.name).collect();
            
            let has_required_role = required_roles.iter().any(|role| user_role_names.contains(role));
            if !has_required_role {
                return Ok(false);
            }
        }
        
        Ok(true)
    }

    async fn matches_resource_condition(&self, condition: &ResourceCondition, resource: &Resource) -> SecurityResult<bool> {
        // 检查服务名称
        if let Some(service) = &condition.service {
            if service != "*" && service != &resource.service {
                return Ok(false);
            }
        }
        
        // 检查资源路径模式
        if let Some(path_pattern) = &condition.path_pattern {
            if path_pattern != "*" && !resource.path.starts_with(path_pattern) {
                return Ok(false);
            }
        }
        
        Ok(true)
    }

    async fn matches_action_condition(&self, condition: &ActionCondition, resource: &Resource) -> SecurityResult<bool> {
        // 检查HTTP方法
        if let Some(methods) = &condition.methods {
            if !methods.contains(&resource.action) && !methods.contains(&"*".to_string()) {
                return Ok(false);
            }
        }
        
        Ok(true)
    }

    async fn matches_environment_condition(&self, condition: &EnvironmentCondition, context: &AuthContext) -> SecurityResult<bool> {
        match &condition.condition_type {
            EnvironmentConditionType::IpAddress => {
                if let Some(client_ip) = &context.client_ip {
                    self.apply_condition_operator(&condition.operator, client_ip, &condition.value)
                } else {
                    Ok(false)
                }
            },
            EnvironmentConditionType::TimeRange => {
                let now = Utc::now().format("%H:%M").to_string();
                self.apply_condition_operator(&condition.operator, &now, &condition.value)
            },
            _ => Ok(true), // 其他条件暂时通过
        }
    }

    fn apply_condition_operator(&self, operator: &ConditionOperator, actual: &str, expected: &str) -> SecurityResult<bool> {
        match operator {
            ConditionOperator::Equals => Ok(actual == expected),
            ConditionOperator::NotEquals => Ok(actual != expected),
            ConditionOperator::Contains => Ok(actual.contains(expected)),
            ConditionOperator::NotContains => Ok(!actual.contains(expected)),
            _ => Ok(true), // 其他操作符暂时通过
        }
    }
}

impl Default for RoleManager {
    fn default() -> Self {
        Self::new()
    }
}

impl Default for PermissionManager {
    fn default() -> Self {
        Self::new()
    }
}